package mqttClient

import (
	"gitee.com/fierce_wolf/go-fox-edge-channel-common/channelAPI"
	"gitee.com/fierce_wolf/go-fox-edge-channel-common/channelParam"
	"gitee.com/fierce_wolf/go-fox-edge-channel-common/channelRestfulNotify"
	"gitee.com/fierce_wolf/go-fox-edge-common/commRedisService"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/ChanSyncObj"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Map"
	"gitee.com/fierce_wolf/go-fox-edge-common/edgeEntity"
	mqtt "github.com/eclipse/paho.mqtt.golang"
	"go-fox-edge-channel-mqtt-client/channelEvent"
	"go-fox-edge-channel-mqtt-client/scriptEngine"
)

type mqttHandler struct {
	clientId  string // 客户端的id
	subscribe string // 订阅的topic
}

func (e *mqttHandler) Handler() mqtt.MessageHandler {
	return func(client mqtt.Client, msg mqtt.Message) {
		topic := msg.Topic()
		payload := msg.Payload()

		operationKeys := scriptEngine.OperationKeys(e.subscribe)
		if len(operationKeys) == 0 {
			return
		}

		for _, operationKey := range operationKeys {
			engine, _ := scriptEngine.GetScriptEngine(operationKey)
			if engine == nil {
				continue
			}

			// 解析数据
			recordList, err := engine.Decode(e.subscribe, topic, payload)
			if err != nil || len(recordList) == 0 {
				continue
			}

			record := recordList[0]
			deviceKey := record["deviceKey"].(string)

			// 通知信息到达
			if ChanSyncObj.IsWaiting(deviceKey) {
				// 问答类型：正在处于问答状态，通知数据到达

				deviceKey = record["deviceKey"].(string)
				channelKey := record["channelKey"].(string)
				channelParam := record["channelParam"].(map[string]interface{})
				manufacturer := Map.GetString(record, "manufacturer", "")
				deviceType := Map.GetString(record, "deviceType", "")
				deviceName := Map.GetString(record, "deviceName", "")
				deviceParam := Map.GetMap(record, "deviceParam", make(map[string]interface{}))

				// 发出创建通道的消息
				e.CreateChannel(channelKey, channelParam)
				e.CreateDevice(manufacturer, deviceType, deviceName, channelKey, deviceParam)

				// 问答类型：正在处于问答状态，通知数据到达
				ChanSyncObj.Notify(deviceKey, payload)
			} else {
				// 主动上报：主动上报数据

				for _, record = range recordList {
					deviceKey = record["deviceKey"].(string)
					channelKey := record["channelKey"].(string)
					channelParam := record["channelParam"].(map[string]interface{})
					manufacturer := Map.GetString(record, "manufacturer", "")
					deviceType := Map.GetString(record, "deviceType", "")
					deviceName := Map.GetString(record, "deviceName", "")
					deviceParam := Map.GetMap(record, "deviceParam", make(map[string]interface{}))

					// 发出创建通道的消息
					e.CreateChannel(channelKey, channelParam)
					e.CreateDevice(manufacturer, deviceType, deviceName, channelKey, deviceParam)

					// 主动上报：主动上报数据
					message := make(map[string]interface{})
					message["channelName"] = channelKey
					message["channelParam"] = channelParam
					message["deviceKey"] = deviceKey
					message["payload"] = record["payload"]

					channelEvent.List.Notify(message)

					//fmt.Println(time.Now().String() + ":" + channelKey)

					// 向API框架发出信号：有数据需要上报了，调用PopAll()吧
					channelAPI.Service.NotifyReport()
				}
			}
		}
	}
}

func (e *mqttHandler) CreateChannel(channelName string, chParam map[string]interface{}) {
	// 检查：该名称的实体是否已经存在
	if channelParam.GetChannelEntity(channelName) != nil {
		return
	}

	// 发出消息
	channelRestfulNotify.CreateChannel(channelName, chParam)
}

func (e *mqttHandler) CreateDevice(manufacturer, deviceType, deviceName, channelName string, deviceParam map[string]interface{}) {
	if manufacturer == "" || deviceType == "" || deviceName == "" || channelName == "" {
		return
	}

	deviceEntity := edgeEntity.Type.DeviceEntity.Instance()
	deviceEntity.Manufacturer = manufacturer
	deviceEntity.DeviceType = deviceType
	deviceEntity.DeviceName = deviceName
	has, err := commRedisService.HasEntityByServiceKey(deviceEntity.Type(), deviceEntity.MakeServiceKey())
	if err != nil || has {
		return
	}

	// 发出消息
	channelRestfulNotify.CreateDevice(manufacturer, deviceType, deviceName, channelName, deviceParam)
}
